package web_controller

import (
	"github.com/duke-git/lancet/v2/convertor"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"strconv"
	"strings"
	"transport/framework/fw_db/fw_db_self"
	"transport/framework/fw_middleware"
	"transport/framework/fw_utils"
	"transport/web/web_mapper"
	"transport/web/web_model"
	"transport/web/web_vo"
)

type transBillController struct {
}

func (controller *transBillController) ItemById(c *gin.Context) {
	id, _ := convertor.ToInt(c.Param("id"))
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	item, err := mapper.QueryById(id)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, item, "ok")
}
func (controller *transBillController) BillAndOrders(c *gin.Context) {
	id, _ := convertor.ToInt(c.Param("id"))
	var retData web_vo.DriverLoadRet
	err := fw_db_self.GetSqliteDB().Transaction(func(tx *gorm.DB) error {
		mapperBill := web_mapper.TransBillMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperOrder := web_mapper.OrderrMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperOrderDetail := web_mapper.OrderDetailMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		// 获取单据信息
		itemBill, err := mapperBill.QueryById(id)
		if err != nil {
			return err
		}
		//获取订单信息
		itemOrders, _, err := mapperOrder.List(itemBill.Sn, "")
		if err != nil {
			return err
		}
		// 获取明细信息
		orderDetails, err := mapperOrderDetail.QueryOrderDetailsByBillId(itemBill.Sn)
		if err != nil {
			return err
		}
		// 组装返回
		retData.BillHeader = itemBill
		for _, v := range itemOrders {
			var orderInfos web_vo.DriverOrderRet
			orderInfos.Order = v
			for _, n := range orderDetails {
				if n.OrderCode == v.OrderCode {
					orderInfos.OrderDetails = append(orderInfos.OrderDetails, n)
				}
			}
			retData.BillOrders = append(retData.BillOrders, &orderInfos)
		}
		return nil
	})
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, retData, "ok")
}

func (controller *transBillController) DelById(c *gin.Context) {
	id, _ := convertor.ToInt(c.Param("id"))
	err := fw_db_self.GetSqliteDB().Transaction(func(tx *gorm.DB) error {
		mapperBill := web_mapper.TransBillMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperOrder := web_mapper.OrderrMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		err := mapperBill.DeleteById(id)
		if err != nil {
			return err
		}
		err = mapperOrder.UpdateOrderToUnbind(id)
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *transBillController) DelByIds(c *gin.Context) {
	var ids []int64
	err := c.ShouldBindJSON(&ids)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	err = fw_db_self.GetSqliteDB().Transaction(func(tx *gorm.DB) error {
		mapperBill := web_mapper.TransBillMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperOrder := web_mapper.OrderrMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		err = mapperBill.DeleteByIds(ids)
		if err != nil {
			return err
		}
		for _, v := range ids {
			err = mapperOrder.UpdateOrderToUnbind(v)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *transBillController) CreateOrUpdateItem(c *gin.Context) {
	var data web_model.TransBill
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	if data.ID == 0 {
		data.Sn = fw_utils.BizCode()
	}
	_, err = mapper.CreateOrUpdate(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *transBillController) CreateItem(c *gin.Context) {
	var data web_model.TransBill
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	ret, err := mapper.Create(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, ret, "ok")
}
func (controller *transBillController) BatchBill(c *gin.Context) {

	err := fw_db_self.GetSqliteDB().Transaction(func(tx *gorm.DB) error {
		mapperBill := web_mapper.TransBillMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperOrder := web_mapper.OrderrMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		mapperRoute := web_mapper.RouteMapper{
			DB:   tx,
			Ctx:  c,
			Lock: fw_db_self.GetSqliteLock(),
		}
		routeList, _, err := mapperRoute.List()
		if err != nil {
			return err
		}
		notBindOrders, err := mapperOrder.QueryNotBind()
		if err != nil {
			return err
		}
		mapRouteTemp := make(map[string][]*web_model.TransOrder, 0)
		for _, v := range notBindOrders {
			mapRouteTemp[v.Route+"-"+v.TransTempType] = append(mapRouteTemp[v.Route+"-"+v.TransTempType], v)
		}
		for k, v := range mapRouteTemp {
			// 找到线路对应的运输信息
			var curRoute web_model.TransRoute
			kInfo := strings.Split(k, "-")
			if len(kInfo) != 2 {
				continue
			}
			for _, n := range routeList {
				if n.Name == kInfo[0] {
					curRoute = *n
					break
				}
			}
			var modelBill web_model.TransBill
			modelBill.Sn = fw_utils.BizCode()
			modelBill.CarrierName = curRoute.CarrierName
			modelBill.CarrierID = curRoute.CarrierID
			modelBill.CarSn = curRoute.CarSn
			modelBill.CarID = curRoute.CarID
			modelBill.DriverName = curRoute.DriverName
			modelBill.DriverID = curRoute.DriverID
			modelBill.Status = "2"
			_, err = mapperBill.Create(&modelBill)
			if err != nil {
				return err
			}
			for _, j := range v {
				j.TransBillSn = modelBill.Sn
				j.TransBillID = modelBill.ID
				_, err = mapperOrder.CreateOrUpdate(j)
				if err != nil {
					return err
				}
			}
		}
		return nil
	})
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, "", "ok")
}
func (controller *transBillController) UpdateItem(c *gin.Context) {
	var data web_model.TransBill
	err := c.ShouldBindJSON(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	ret, err := mapper.Update(&data)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.OK(c, ret, "ok")
}
func (controller *transBillController) Page(c *gin.Context) {
	var err error
	var from, limit = 1, 10
	if tmp := c.Request.FormValue("pageSize"); tmp != "" {
		limit, _ = strconv.Atoi(tmp)
	}
	if tmp := c.Request.FormValue("pageIndex"); tmp != "" {
		from, _ = strconv.Atoi(tmp)
	}
	sn := c.Request.FormValue("sn")
	carrierId := c.Request.FormValue("carrierId")
	carId := c.Request.FormValue("carId")
	driverId := c.Request.FormValue("driverId")
	status := c.Request.FormValue("status")
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.Page(from, limit, sn, carrierId, carId, driverId, status)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.PageOK(c, items, total, from, limit, "ok")
}
func (controller *transBillController) PageApp(c *gin.Context) {
	var err error
	var from, limit = 1, 10
	if tmp := c.Request.FormValue("limit"); tmp != "" {
		limit, _ = strconv.Atoi(tmp)
	}
	if tmp := c.Request.FormValue("from"); tmp != "" {
		from, _ = strconv.Atoi(tmp)
	}
	tabIndex := c.Request.FormValue("tabIndex")
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.PageApp(from, limit, tabIndex)
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.PageOK(c, items, total, from, limit, "ok")
}
func (controller *transBillController) List(c *gin.Context) {
	var err error
	mapper := web_mapper.TransBillMapper{
		DB:   fw_db_self.GetSqliteDB(),
		Ctx:  c,
		Lock: fw_db_self.GetSqliteLock(),
	}
	items, total, err := mapper.List()
	if err != nil {
		fw_utils.Error(c, -1, err, "")
		return
	}
	fw_utils.ListOK(c, items, total, "ok")
}

func TransBillRoute(r *gin.Engine) {
	controller := transBillController{}
	v1 := r.Group("/trans").Use(fw_middleware.JwtAuthMiddleware())
	{
		v1.GET("/v1/transBill/page", controller.Page)
		v1.GET("/v1/transBill/pageApp", controller.PageApp)
		v1.GET("/v1/transBill/list", controller.List)
		v1.GET("/v1/transBill/:id", controller.ItemById)
		v1.GET("/v1/transBillAndOrder/:id", controller.BillAndOrders)
		v1.DELETE("/v1/transBill/:id", controller.DelById)
		v1.DELETE("/v1/transBill/batchByIds", controller.DelByIds)
		v1.PUT("/v1/transBill", controller.UpdateItem)
		v1.POST("/v1/transBill", controller.CreateItem)
		v1.POST("/v1/transBillItemCreateOrUpdate", controller.CreateOrUpdateItem)
		v1.POST("/v1/batchBill", controller.BatchBill)
	}
}
